<?php
namespace app\api\controller;

use app\api\job\PlayerReport;
use think\Controller;
use think\facade\Log;
use think\Db;
use app\common\model\Player;
use think\Queue;
use think\Antiaddiction;


class UserAuth extends Controller
{

    //囧逗
    //应用标识（APPID）
    public $appId = 'a0148ef2d30c4c1ba04e84d44614fa07';//2c842c4588f44f75a67a9bfcd38be173
    //用户密钥（Secret Key）：
    public $secretKey = '5d37fb0a9d397ce2d549231d568bbe46';// 5d37fb0a9d397ce2d549231d568bbe46  a744198000cb80b1746a0082ed436827
    //游戏备案识别码（bizId）
    public $bizId = '1199006324';// 女神联盟

    public $antiapi = NULL;

    public function initialize()
    {
        $this->antiapi = new Antiaddiction();
        $this->antiapi->initialize($this->appId , $this->secretKey , $this->bizId);
    }

    /**
     * 实名认证
     */
    public function auth(){
        // 获取通知参数
        $params = $this->request->post();
        $route = $this->request->route();

        log::info('实名认证请求用户数据：' . json_encode($params));
        if(empty($params)){
            echo json_encode(['success'=>false,'code'=>"1004",'msg'=>'data not null.']);exit;
        }
        $name = aes_cbc_decrypt($params['name']);
        $id_number = aes_cbc_decrypt($params['idCardNo']);

        //数据验证
        if(!checkName($name)){
            echo json_encode(['success'=>false,'code'=>"1004",'msg'=>'name is invalid.']);exit;
        }
        if(!check_idcard($id_number)){
            echo json_encode(['success'=>false,'code'=>"1001",'msg'=>'identity number is invalid.']);exit;
        }
        $ip = $this->request->ip();
        if(!isset($ip)||!filter_var($ip, FILTER_VALIDATE_IP)||empty($ip)){
            echo json_encode(['success'=>false,'code'=>"1006",'msg'=>'ip is invalid.']);exit;
        }
        //签名验证
        if(!self::check_sign($params)){
            echo json_encode(['success'=>false,'code'=>"1006",'msg'=>'sign is invalid.']);exit;
        }
        $where['real_name'] = trim($name);
        $where['id_card'] = trim($id_number);

        //用户信息
        $player = Player::getOne(['account'=>"g_".$params['userId']]);
        if(empty($player)){
            $data['account'] = "g_".$params['userId'];
            $data['password'] = get_encrypt('123456');
            $data['type'] = 0;
            $data['cid'] = $route['cid'] ?? "5";
            $data['gid'] = "0";
            //注册
            try {
                Db::startTrans();
                $player = Player::register($data);
                Db::commit();
            }catch (Exception $e) {
                Db::rollback();
                Log::info("用户注册失败:".$e->getMessage());
            }
        }
        if(stripos($ip,"59.82") === false){
            //实名认证
            $count_where[] = ['request_ip','=',$ip];
            $count_where[] = ['create_time','between',[date('Y-m-d 00:00:00',time()),date('Y-m-d 23:59:59',time())]];
            $ip_count = DB::connect('db_config_aiqi')->name('real_auth_log')
                ->where($count_where)
                ->count();
            if($ip_count > 10){
                echo json_encode(['code'=>"1006",'msg'=>'ip requested too many.']);exit;
            }
        }

        //查询是否实名认证
        $auth = DB::connect('db_config_aiqi')->name('real_auth')
            ->where($where)
            ->find();
        if(null == $auth){

            log::info('实名认证用户数据：' . json_encode($params));
            $check = new PlayerAuth();
            $result = $check->checkIdCard($name,$id_number);
            log::info('实名认证返回数据：' . json_encode($result));
            //记录日志
            $auth_log = [
                "uid"=>$player['id'] ?? 0,
                "real_name"=>$name,
                "id_card"=>$id_number,
                "request_ip"=>$ip,
            ];
            DB::connect('db_config_aiqi')->name('real_auth_log')->insert($auth_log);

            if($result['errcode'] > 0){
                echo json_encode(['code'=>"1006",'msg'=>'user auth fail.']);exit;
            }
            if($result['data']['result']['status'] > 0){
                echo json_encode(['code'=>"1006",'msg'=>'user auth fail.']);exit;
            }
            $auth_log['pi'] = $result['data']['result']['pi'];
            DB::connect('db_config_aiqi')->name('real_auth')->insert($auth_log);
        }else{
            //记录日志
            $auth_log = [
                "uid"=>$player['id'] ?? 0,
                "real_name"=>$name,
                "id_card"=>$id_number,
                "request_ip"=>$ip,
            ];
            DB::connect('db_config_aiqi')->name('real_auth_log')->insert($auth_log);
        }
        $idInfo = getIDCardInfo($id_number);
        //更新用户实名认证状态
        $player->age = $idInfo['age'];
        $player->is_age = $idInfo['isAdult'] ? 2 : 1;
        $player->save();
        $pi = $auth['pi'] ?? $result['data']['result']['pi'];
        //添加redis队列、通知到游戏
        $collections = [
            'no'=>1,
            'bt'=>1,  ///游戏用户行为类型 0：下线 1：上线
            'ct'=>0,  ///用户行为数据上报类型 0：已认证通过用户 2：游客用户
            'di'=>md5($pi),
            'pi'=>$pi,
            'ot'=> time(),
        ];
        Queue::push(PlayerReport::class, json_encode($collections));
        echo json_encode(['success'=>true,'code'=>"0",'msg'=>'success','signature'=>$params['signature'],'signatureMethod'=>$params['signatureMethod']]);exit;
    }

    public function reportLogInOut()
    {
        $data =  $this->request->post();
        $appid = $this->appId;
        $pi = $data['pi'];
        $bt = $data['bt'];
        $ct = $data['ct'];
        $url_path = 'http://api2.wlc.nppa.gov.cn/behavior/collection/loginout';
        $data = [
            'collections'=>[
                [
                    'no'=> 1,
                    'si'=> md5($appid . $pi),//一个会话标识只能对应唯一的实名用户，一个实名用户可以拥有多个会话标识；同一用户单次游戏会话中，上下线动作必须使用同一会话标识上报备注：会话标识仅标识一次用户会话，生命周期仅为一次上线和与之匹配的一次下线，不会对生命周期之外的任何业务有任何影响
                    'bt'=> $bt,  ///游戏用户行为类型 0：下线 1：上线
                    'ot'=> time(),
                    'ct'=> $ct,  ///用户行为数据上报类型 0：已认证通过用户 2：游客用户
//                    'di'=> "ecvndx6r6xfwofmufs3lbimcr639r33t", ///'ecvndx6r6xfwofmufs3lbimcr639r33t',
                    'pi'=> $pi,
                ]
            ],
        ];
        //var_dump(json_encode($data));
        $ret = $this->antiapi->api_post($url_path,$data);
        return json_encode($ret);
    }

    public function reportLogInOutJob($data)
    {
        $appid = $this->appId;
        $pi = $data['pi'];
        $bt = $data['bt'];
        $ct = $data['ct'];
        $ot = $data['ot'];
        $url_path = 'http://api2.wlc.nppa.gov.cn/behavior/collection/loginout';
        $data = [
            'collections'=>[

                [
                    'no'=> 1,
                    'si'=> md5($appid . $pi),//一个会话标识只能对应唯一的实名用户，一个实名用户可以拥有多个会话标识；同一用户单次游戏会话中，上下线动作必须使用同一会话标识上报备注：会话标识仅标识一次用户会话，生命周期仅为一次上线和与之匹配的一次下线，不会对生命周期之外的任何业务有任何影响
                    'bt'=> $bt,  ///游戏用户行为类型 0：下线 1：上线
                    'ot'=> $ot,
                    'ct'=> $ct,  ///用户行为数据上报类型 0：已认证通过用户 2：游客用户
//                    'di'=> "ecvndx6r6xfwofmufs3lbimcr639r33t", ///'ecvndx6r6xfwofmufs3lbimcr639r33t',
                    'pi'=> $pi,
                ]
            ],
        ];
        $ret = $this->antiapi->api_post($url_path,$data);
        return json_encode($ret);
    }

    private static function check_sign($params)
    {
        $return = true;
        $publiceKey  = openssl_pkey_get_public("file://".__DIR__."/../../../public/pay/gaode/rsa_public_key.pem");
        if(strrpos($params['signature'], "%2F")){
            $params['signature'] = urldecode($params['signature']);
        }
        $sign = base64_decode($params['signature']);
        unset($params['signature']);
        unset($params['signatureMethod']);
        ksort($params);
        $str = '';
        foreach ($params as $k => $v) {
            $str .= $k.'='.$v.'&';
        }
        $str = rtrim($str,'&');
        $res = openssl_verify($str, $sign, $publiceKey,OPENSSL_ALGO_SHA256);
        if(!$res){
            $return = false;
        }
        return $return;
    }
}
